class myVue {
    constructor(options) {
        this.$options = options;
        
        // 创造前
        if( typeof this.$options.beforeCreat == "function"){
            this.$options.beforeCreat.bind(this)()
        }
 
        this.$el = document.querySelector(this.$options.el);

        this.observer();
        this.proxyData();
       
        // 创造后
        if( typeof this.$options.created == "function"){
            this.$options.created.bind(this)()
        }
        this.watchEvent = {}
        
       // 编译前
        if( typeof this.$options.beforeMount == "function"){
            this.$options.beforeMount.bind(this)()
        }    
         
        this.compile(this.$el);

           // 编辑后
        if( typeof this.$options.Mounted == "function"){
            this.$options.Mounted.bind(this)()
        }    
    }

    proxyData() {
        for (let key in this.$options.data) {
            Object.defineProperty(this, key, {
                enumerable: true,
                configurable: false,
                get() {
               
                    return this.$options.data[key];
                },
                set(value) {          
                    this.$options.data[key] = value
                }
            })
        }

    }

    observer() {
        // 劫持事件
        let self = this
        for (let key in this.$options.data) {

            let value = this.$options.data[key]

            Object.defineProperty(this.$options.data, key, {
                enumerable: true,
                configurable: false,
                set(val) {
                    value = val
                    self.watchEvent[key].forEach((item) => {
                        item.updated()
                    })
                },
                get() {

                    return value
                }
            })
        }
    }

    compile(pNode) {
       pNode.childNodes.forEach((node, index) => {
            // 元素节点
            if (node.nodeType === 1) {
                // v-html
                if (node.getAttribute("v-html")) {
                    let vmKey = node.getAttribute("v-html").trim()
                    // 初次加载渲染数据
                    node.innerHTML = this[vmKey];

                    // 添加到事件队列中
                    let oneWatch = new Watch(this, vmKey, node, "innerHTML");
                    if (this.watchEvent[vmKey]) {
                        this.watchEvent[vmKey].push(oneWatch)
                    } else {
                        this.watchEvent[vmKey] = []
                        this.watchEvent[vmKey].push(oneWatch)
                    }
                    node.removeAttribute('v-html')

                }
                // v-model
                if (node.getAttribute("v-model")) {
                    let vmKey = node.getAttribute("v-model").trim()
                    node.value = this[vmKey]

                     // 添加到事件队列中
                     let oneWatch = new Watch(this, vmKey, node, "value");
                     if (this.watchEvent[vmKey]) {
                         this.watchEvent[vmKey].push(oneWatch)
                     } else {
                         this.watchEvent[vmKey] = []
                         this.watchEvent[vmKey].push(oneWatch)
                     }

                     // 双向绑定
                     node.addEventListener('input', ()=>{
                         this[vmKey]  = node.value
                     })
                     node.removeAttribute('v-model')
                }
                       
                   // 绑定点击事件
                if (node.getAttribute("@click")){
                    let vmKey = node.getAttribute("@click")
                    node.addEventListener("click",(event)=>{
                        this.$options.methods[vmKey].bind(this)();
                    })
                }

                if(node.childNodes.length　>= 1 ){
                        this.compile(node)
           
                }
            }

            // 文本节点
            if (node.nodeType === 3) {  
                              
                node.textContent = node.textContent.replace(/\{\{(.*)?\}\}/,(v,vmKey)=>{
                    vmKey = vmKey.trim()
                    
                     let oneWatch = new Watch(this, vmKey, node, "textContent");
                     if (this.watchEvent[vmKey]) {
                         this.watchEvent[vmKey].push(oneWatch)
                     } else {
                         this.watchEvent[vmKey] = []
                         this.watchEvent[vmKey].push(oneWatch)
                     }
                     return this[vmKey]

               
                })


                         
            }



        });

    }


}

class Watch {
    constructor(vm, vmKey, node, attr) {
        this.vm = vm;
        this.vmKey = vmKey
        this.node = node;
        this.attr = attr
    }

    updated() {

        // 更新前

        if(typeof this.vm.$options.beforeUpdate == 'function'){
            options.beforeUpdate.bind(this.vm)()
        }
        this.node[this.attr] = this.vm[this.vmKey]
          // 更新后
        if(typeof this.vm.$options.updated == 'function'){
            options.updated.bind(this.vm)()
        }
    }
}